import json
from student.utils.pagination import Pagination
from django.shortcuts import render, redirect, HttpResponse
from django import forms
from . import models
from block import BlockChainOperation
from block.BlockChain import str_to_dict_method, transtodict_method
from io import BytesIO
from . import verify
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse

class ManageModelForm(forms.ModelForm):
    # 对密码进行长度限制
    password = forms.CharField(min_length=6, label="密码")

    class Meta:
        model = models.ManageInfo
        fields = ["user", "password"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            # print(name, field)
            field.widget.attrs = {"class": "form-control"}


class StudentModelForm(forms.ModelForm):
    # 对密码进行长度限制

    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", "account", "create_time", "mark", "gender"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            # print(name, field)
            field.widget.attrs = {"class": "form-control"}


def student_add(request):
    if request.method == "GET":
        form = StudentModelForm
        return render(request, 'student_add.html', {"form": form})
    form = StudentModelForm(data=request.POST)
    last_blockinfo = BlockChainOperation.get_last_block()
    if form.is_valid():
        # 判定是否存在创世区块，如无则创建
        if last_blockinfo is None:
            start_block = BlockChainOperation.create_generate_block()
            BlockChainOperation.save_to_BlockInfo(0, 'Genesis Block', start_block)
        data_list = form.cleaned_data
        new_block = BlockChainOperation.add_block(data_list)
        BlockChainOperation.save_to_BlockInfo(data_list['account'], data_list['name'], new_block)
        print("prev_hash", new_block["prev_hash"])
        form.save()
        return redirect('/student/manage/?page=1')
    return render(request, 'student_add.html', {"form": form})


def student_manage(request):
    # 如果有搜索条件
    value = request.GET.get("v")
    form = BlockChainOperation.get_block_all()
    if value:
        form = BlockChainOperation.get_some_block(value)
    count = form.count()
    p = Pagination(request, form, count)
    form = p.form[1:]
    page_string = p.page_string
    return render(request, "student_manage.html", {"form": form, "page_string": page_string})


def student_find(request, nid):
    blockinfo = BlockChainOperation.get_block(account=nid)
    block_id = blockinfo.id
    real_hash = BlockChainOperation.get_nextblock_prevhash(block_id + 1)
    student = models.UserInfo.objects.filter(account=nid).first()
    block = str_to_dict_method.str_to_dict(blockinfo.block)
    student_dict = transtodict_method.transtodict(student.name, student.password, student.age, student.account,
                                                  student.create_time, student.mark, student.gender)
    block['data'] = str([student_dict])
    block = json.dumps([block])
    block = str_to_dict_method.str_to_dict(block)
    hash = BlockChainOperation.hash(block)
    return render(request, 'student_find.html', {"student": student, "hash": hash, "real_hash": real_hash})


class ManageLoginForm(forms.Form):
    user = forms.CharField(label="用户名", widget=forms.TextInput(attrs={"class": "form-control"}))
    password = forms.CharField(label="密码", widget=forms.PasswordInput(attrs={"class": "form-control"}))
    code = forms.CharField(label="验证码", widget=forms.TextInput(attrs={"class": "form-control"}))


def manage_login(request):
    if request.method == "GET":
        form = ManageLoginForm
        return render(request, "manage_login.html", {"form": form})
    form = ManageLoginForm(data=request.POST)
    if form.is_valid():
        data_list = form.cleaned_data
        print(data_list)

        # 检验验证码
        code = data_list.pop('code')
        right_code = request.session.get('code')
        if code.upper() != right_code.upper():
            form.add_error("code", "验证码错误")
            return render(request, "manage_login.html", {"form": form})

        result = models.ManageInfo.objects.filter(**data_list).first()
        if not result:
            form.add_error("password", "登录失败，账号或密码错误")
            return render(request, "manage_login.html", {"form": form})

        # 用户名和密码正确
        request.session["info"] = result.user
        request.session.set_expiry(60 * 60 * 24 * 7)
        return redirect('/student/manage/?page=1')
    return render(request, "manage_login.html", {"form": form})


class StudentLoginForm(forms.Form):
    account = forms.CharField(label="学号", widget=forms.TextInput(attrs={"class": "form-control"}))
    password = forms.CharField(label="密码", widget=forms.PasswordInput(attrs={"class": "form-control"}))
    code = forms.CharField(label="验证码", widget=forms.TextInput(attrs={"class": "form-control"}))


def student_login(request):
    if request.method == "GET":
        form = StudentLoginForm
        return render(request, 'student_login.html', {"form": form})
    form = StudentLoginForm(request.POST)
    if form.is_valid():
        data_list = form.cleaned_data

        # 检验验证码
        code = data_list.pop("code")
        right_code = request.session['code']
        if code.upper() != right_code.upper():
            form.add_error("code", "验证码错误")
            return render(request, 'student_login.html', {"form": form})

        # 检验账号密码是否有效
        result = models.UserInfo.objects.filter(**data_list).first()
        if not result:
            form.add_error("password", "账号或密码错误")
            return render(request, 'student_login.html', {"form": form})
        request.session['info'] = {"account":result.account,"name":result.name}
        request.session.set_expiry(60 * 60 * 24 *7)
        return redirect('/student/'+result.account+'/list')
    return render(request, 'student_login.html', {"form": form})

def image_code(request):
    img, code = verify.check_code()
    stream = BytesIO()
    img.save(stream, 'png')

    # 网站生成随机字符串；写到用户浏览器的cookie中，再写入session中
    # 将code写入到用户的session中
    request.session['code'] = code
    request.session.set_expiry(60)
    return HttpResponse(stream.getvalue())

def student_list(request, nid):
    blockinfo = BlockChainOperation.get_block(account=nid)
    block_id = blockinfo.id
    real_hash = BlockChainOperation.get_nextblock_prevhash(block_id + 1)
    student = models.UserInfo.objects.filter(account=nid).first()
    block = str_to_dict_method.str_to_dict(blockinfo.block)
    student_dict = transtodict_method.transtodict(student.name, student.password, student.age, student.account,
                                                  student.create_time, student.mark, student.gender)
    block['data'] = str([student_dict])
    block = json.dumps([block])
    block = str_to_dict_method.str_to_dict(block)
    hash = BlockChainOperation.hash(block)
    return render(request, 'student_list.html', {"student": student, "hash": hash, "real_hash": real_hash})

def logout(request):
    """注销"""
    request.session.clear()
    return redirect('/manage/login/')

def chart(request):
    return render(request,'chart.html')

def chart_pillar(request):
    result = {
        "status": True,
        "data": [5, 10, 56]
    }
    return JsonResponse(result)

